package com.atwisdom.star.core.dsl.modelClass.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.core.dao.pojo.modelClass.consume.ConsumeInstance;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class QueryBuilder {
    //模型所有字段
    private final String[] modelFields = {"id", "type", "className", "version", "properties","statusProperties","published", "web", "others", "comments", "deleteFlag", "updatedBy", "updateTime", "createdBy", "createTime"};
    //摘要字段
    private final String[] infoSelection = {"id", "className", "type", "version", "others", "published","comments", "updatedBy", "updateTime", "createdBy", "createTime"};
    //逻辑运算符对照表
    private final JSONObject operatorMap = JsonUtil.buildJson(new Object[]{"==", " = ","!=", " <> ","≠", " <> ","≥", " >= ","≤", " <= ","&&", " AND ","\\|\\|", " OR ","!", " NOT "});

    public <T> QueryWrapper<T> createQuery(Boolean published,String selection,String orderBy,String defaultOrderBy){
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        if (published != null) {
            queryWrapper.eq("published", published);
        }
        if(!StringUtils.isEmpty(selection)){
            queryWrapper.select(selection);
        }
        this.buildOrderBy(queryWrapper, orderBy, defaultOrderBy);
        return queryWrapper;
    }
    /**
     * 搞摘要查询wrapper
     *
     * @param wrapper 参数
     */
    public void buildInfoSelection(QueryWrapper<?> wrapper) {
        if (wrapper == null) {
            wrapper = new QueryWrapper<>();
        }
        wrapper.select(infoSelection);
    }

    /**
     * 查询wrapper
     *
     * @param wrapper 参数
     */
    public void buildModelFields(QueryWrapper<?> wrapper) {
        if (wrapper == null) {
            wrapper = new QueryWrapper<>();
        }
        wrapper.select(modelFields);
    }



    /**
     * 构建排序对象
     *
     * @param queryWrapper   查询wrapper
     * @param orderBy        排序字段
     * @param defaultOrderBy 默认排序字段
     * @param <T>            泛型类型
     * @return 返l回 排序wrapper
     */
    public <T> QueryWrapper<T> buildOrderBy(QueryWrapper<T> queryWrapper, String orderBy, String defaultOrderBy) {
        Map<String, List<String>> orderByMap = new HashMap<>();
        if (StringUtils.isNotBlank(orderBy)) {
            List<String> orderList = Arrays.asList(orderBy.split(";"));
            orderList.forEach(o -> {
                if (o.indexOf("asc") > 0) {
                    o = o.replaceAll(",asc", "");
                    List<String> ascList = Arrays.asList(o.split(","));
                    orderByMap.put("asc", ascList);
                } else if (o.indexOf("desc") > 0) {
                    o = o.replaceAll(",desc", "");
                    List<String> descList = Arrays.asList(o.split(","));
                    orderByMap.put("desc", descList);
                }
            });
        }
        if (orderByMap.size() > 0) {
            for (String key : orderByMap.keySet()) {
                if (key.equalsIgnoreCase("desc")) {
                    queryWrapper.orderByDesc(orderByMap.get(key));
                } else {
                    queryWrapper.orderByAsc(orderByMap.get(key));
                }
            }
        } else {
            List<String> columns = Arrays.asList(defaultOrderBy.split(","));
            queryWrapper.orderByDesc(columns);
        }
        return queryWrapper;
    }


    /**
     * 操作符转换
     *
     * @param condition 转换参数
     */
    public String transformOperator(String condition) {
        if(StringUtils.isBlank(condition)){
            return null;
        }
        List<Operator> operatorList = this.getOperatorType();
        for (Operator operator : operatorList) {
            String key = operator.getKey();
            String value = operator.getValue();
            condition = condition.replaceAll(key, value);
        }
//        for ( String key: operatorMap.keySet()) {
//            condition = condition.replaceAll(key, operatorMap.getString(key));
//        }
        return condition;
    }

    /**
     * 数学操作符与sql操作符映射
     *
     * @return 返回操作数据
     */
    public List<Operator> getOperatorType() {
        List<Operator> operators = new ArrayList<>();
        operators.add(new Operator(1, "==", " = "));
        operators.add(new Operator(2, "!=", " <> "));
        operators.add(new Operator(3, "≠", " <> "));
        operators.add(new Operator(4, "≥", " >= "));
        operators.add(new Operator(5, "≤", " <= "));
        operators.add(new Operator(6, "&&", " AND "));
        operators.add(new Operator(7, "\\|\\|", " OR "));
        operators.add(new Operator(8, "!", " NOT "));
        return operators;
    }

    /**
     * 获取新版号
     *
     * @param version 原版本
     * @return 返回新版本号
     */
    public BigDecimal getNewVersion(BigDecimal version) {
        if (version == null) {
            return new BigDecimal("1.0");
        }

        return version.add(new BigDecimal("1.0"));
    }

    /**
     * 从查询条件中解析出className 值
     *
     * @param condition 查询条件
     * @return 返回结果
     */
    public String getClassNameBy(String condition) {
        if (StringUtils.isBlank(condition)) {
            return null;
        }
        String s = condition.replaceAll("==", "=").replaceAll(" ", "");
        int start = s.indexOf("className='");
        String className = null;
        if (start < 0) {
            return null;
        }
        String classNameOpt = s.substring(start + "className='".length());
        int end = classNameOpt.indexOf("'");

        //匹配中文，英文字母和数字及下划线
        String reg1 = "^[a-zA-Z\\d_\\u4e00-\\u9fa5]+$";
        Pattern pattern = Pattern.compile(reg1);
        Matcher matcher = pattern.matcher(classNameOpt.substring(0, end));
        if (matcher.matches()) {
            className = classNameOpt.substring(0, end);
        }
        return className;
    }


    /**
     * 从查询条件中解析出parentId 值
     *
     * @param condition 查询条件
     * @return 返回结果
     */
    public String getParentIdBy(String condition) {
        if (StringUtils.isBlank(condition)) {
            return null;
        }
        String s = condition.replaceAll("==", "=").replaceAll(" ", "");
        int start = s.indexOf("parentId='");
        String parentId = null;
        if (start < 0) {
            return null;
        }
        String classNameOpt = s.substring(start + "parentId='".length());
        int end = classNameOpt.indexOf("'");

        //匹配中文，英文字母和数字及下划线
        String reg1 = "^[a-zA-Z\\d_\\u4e00-\\u9fa5]+$";
        Pattern pattern = Pattern.compile(reg1);
        Matcher matcher = pattern.matcher(classNameOpt.substring(0, end));
        if (matcher.matches()) {
            parentId = classNameOpt.substring(0, end);
        }
        return parentId;
    }


    /**
     * 处理hierProperties
     * @param hierProperties 参数
     * @return 返回hier json 结构
     */
    public JSONObject fetchHierBy(JSONObject hierProperties, JSONObject hier) {
        String type = hierProperties.getString("type");
        JSONObject hierJson = new JSONObject();
        switch (type) {
            case "list":
                hierJson = ListHier.fetchUpdateHier(hierProperties, hier);
                break;
            case "dictionary":
                hierJson = DictionaryHier.fetchUpdateHier(hierProperties, hier);
                break;
            case "tree":
                hierJson = TreeHier.fetchUpdateHier(hierProperties, hier);
                break;
            case "chain":
                hierJson = ChainHier.fetchUpdateHier(hierProperties, hier);
                break;
            case "treeChain":
                hierJson = TreeChainHier.fetchHier(hierProperties, hier);
                break;
            default:
                break;
        }

        return hierJson;
    }


    /**
     * 根据name查找hier中Content的节点
     * @param hier 容器
     * @param name 节点名称
     * @return 返回节点jsonObject
     */
    public JSONObject findHierContentNode(JSONObject hier,String name){
        JSONArray content = hier.getJSONArray("content");
        JSONObject result = (JSONObject) content.stream()
                .filter(element -> {
                    if(element instanceof JSONObject) {
                        JSONObject obj = (JSONObject) element;
                        return obj.getString("name").equals(name);
                    }
                    return false;
                })
                .findAny()
                .orElse(null);
        return result;
    }
}
